/******************************************************************************/
/*Files to Include                                                            */
/******************************************************************************/

#include <htc.h>            /* HiTech General Includes */
#include <stdint.h>         /* For uint8_t definition */
#include <stdbool.h>        /* For true/false definition */

#include "define.h"

#define LED_ON1

static const rom uint16_t   bitpattern[] = {
    0x0000, 0x0fff, 0x0ff0, 0x0f0f, 0x0f00, 0x00ff, 0x00f0, 0x000f,
    0x0fff, 0x0ff0, 0x0f0f, 0x0f00, 0x00ff, 0x00f0, 0x000f, 0x0000,
    0x0ff0, 0x0f0f, 0x0f00, 0x00ff, 0x00f0, 0x000f, 0x0000, 0x0fff,
    0x0f0f, 0x0f00, 0x00ff, 0x00f0, 0x000f, 0x0000, 0x0fff, 0x0ff0,
    0x0f00, 0x00ff, 0x00f0, 0x000f, 0x0000, 0x0fff, 0x0ff0, 0x0f0f,
    0x00ff, 0x00f0, 0x000f, 0x0000, 0x0fff, 0x0ff0, 0x0f0f, 0x0f00,
    0x00f0, 0x000f, 0x0000, 0x0fff, 0x0ff0, 0x0f0f, 0x0f00, 0x00ff,
    0x000f, 0x0000, 0x0fff, 0x0ff0, 0x0f0f, 0x0f00, 0x00ff, 0x00f0,
    0x0000, 0x0fff, 0x0ff0, 0x0f0f, 0x0f00, 0x00ff, 0x00f0, 0x000f,
};

bool    t100hz;

static int_fast8_t      t100hz_count;

static int_fast8_t      segCount;
static int_fast16_t     bits[8];
static int_fast16_t     bits_next[8];
static rom uint16_t*    pPattern = bitpattern;
static rom uint16_t*    pLast = bitpattern + (sizeof(bitpattern) >> 1);
#ifdef LED_ON1
static int_fast8_t      bitCount;

static int_fast8_t      patternB[] = {
    0x0001,
    0x0004,
    0x0002,
    0x0008
};

static int_fast8_t      patternR[] = {
    0x0010,
    0x0040,
    0x0020,
    0x0080
};

static int_fast8_t      patternG[] = {
    0x0100,
    0x0400,
    0x0200,
    0x0800
};
#else
static int_fast8_t      rgb[] = {
    0xdf,
    0xbf,
    0x7f,
    0xdf,
    0xbf,
    0x7f,
    0xdf,
    0xbf,
    0x7f,
};

static int_fast16_t seg[] = {
    0x0001,
    0x0010,
    0x0100,
    0x0004,
    0x0040,
    0x0400,
    0x0002,
    0x0020,
    0x0200,
    0x0008,
    0x0080,
    0x0800
};
#endif


/******************************************************************************/
/* Interrupt Routines                                                         */
/******************************************************************************/

void nextPattern( void )
{
    int i;

    memcpy( bits, bits_next, sizeof(bits) );

    if( pPattern == pLast )
    {
        pPattern = bitpattern;
    }
    for( i = 0; i < 8; i++ )
    {
        bits_next[i] = *pPattern++;
    }
}

void intInit(void)
{
    int i;

    for( i = 0; i < 8; i++ )
    {
        bits_next[i] = *pPattern++;
    }
    nextPattern();

    segCount = 0;
#ifdef LED_ON1
    bitCount = 0;
#endif
    LED_COM |= LED_COM_ALL;
    LED_SEG |= LDE_SEG_ALL;

    t100hz = false;
    t100hz_count = 80;
}

void setColor(int bit, int g, int r, int b)
{
#if 0
    bits[bit][0] = b;
    bits[bit][1] = r;
    bits[bit][2] = g;
#endif
}

void interrupt isr(void)
{
    /* This code stub shows general interrupt handling.  Note that these
    conditional statements are not handled within 3 seperate if blocks.
    Do not use a seperate if block for each interrupt flag to avoid run
    time errors. */

    if(T0IF)
    {
        int_fast8_t out;

        T0IF = 0;

#ifdef LED_ON1
        if( segCount == 0 )
        {
            LED_SEG |= LED_SEG_ALL;
            LED_COM = ~(1 << bitCount);
        }
        out = LED_SEG | LED_SEG_ALL;
        if( bits[bitCount] & patternB[segCount] )
        {
            out &= ~0x20;
        }
        if( bits[bitCount] & patternR[segCount] )
        {
            out &= ~0x40;
        }
        if( bits[bitCount] & patternG[segCount] )
        {
            out &= ~0x80;
        }
        LED_SEG = out;

        if( ++segCount == 4 )
        {
            segCount = 0;
            if( ++bitCount == 8 )
            {
                bitCount = 0;
                nextPattern();
            }
        }
#else
        {
            int_fast8_t i;
            int_fast8_t bit;

            LED_COM = LED_COM_ALL;
            LED_SEG = (LED_SEG | LED_SEG_ALL) & rgb[segCount];

            out = 0xff;
            bit = 1;
            for( i = 0; i < 8; i++ )
            {
                if( bits[i] & seg[segCount] )
                {
                    out &= ~bit;
                }
                bit <<= 1;
            }
            LED_COM = out;

            if( ++segcount == sizeof(rgb) )
            {
                segcount = 0;
                nextPattern();
            }
        }
#endif

        if(--t100hz_count == 0)
        {
            t100hz = true;
            t100hz_count = 80;
        }
    }

#if 0

    /* TODO Add High Priority interrupt routine code here. */

    /* Determine which flag generated the interrupt */
    if(<Interrupt Flag 1>)
    {
        <Interrupt Flag 1=0>; /* Clear Interrupt Flag 1 */
    }
    else if (<Interrupt Flag 2>)
    {
        <Interrupt Flag 2=0>; /* Clear Interrupt Flag 2 */
    }
    else
    {
        /* Unhandled interrupts */
    }

#endif

}
